/*
 * dla_Mamy.c
 *
 * Created: 2012-05-28 22:31:09
 *  Author: Sebastian_2
 */ 

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <util/delay.h>
#include "conf.h"
#include "drivers/XMEGA.h"
#include "drivers/ADS7843.h"
#include "drivers/SD/diskio.h"
//#include "drivers/MCP79410.h"
//#include "drivers/TMP431.h"
#include "Globals.h"
#include "Colours.h"
#include "Menus.h"
#include "MP3.h"
#include "misc.h"

volatile uint16_t gColour = BACKGROUND;
point gP1 = {0, 0};
point gP2 = {0, 0};
volatile uint8_t screenCount = 0;
//TWI_Master_t gTWI_Master;

//FIL gVS1003File;
//AudioFile_t gVS1003FileInfo;
//uint8_t gVS1003Buffer1[VS1003_BUFSIZE], gVS1003Buffer2[VS1003_BUFSIZE];
//uint16_t gVS1003BufferLenth = 0;

MAKE_MENU(Menu_Main, Menu_Main_Enter, sizeof(TI_Main)/sizeof(TI_Main[0]), TI_Main);

MAKE_MENU(Menu_MP3, Menu_MP3_Enter, sizeof(TI_MP3)/sizeof(TI_MP3[0]), TI_MP3);
MAKE_MENU(Menu_Player, Menu_Player_Enter, sizeof(TI_Player)/sizeof(TI_Player[0]), TI_Player);
MAKE_MENU(Menu_Artists, Menu_Artists_Enter, sizeof(TI_Artists)/sizeof(TI_Artists[0]), TI_Artists);
MAKE_MENU(Menu_Songs, Menu_Songs_Enter, sizeof(TI_Songs)/sizeof(TI_Songs[0]), TI_Songs);

MAKE_MENU(Menu_Radio, Menu_Radio_Enter, sizeof(TI_Radio)/sizeof(TI_Radio[0]), TI_Radio);
MAKE_MENU(Menu_RStations, Menu_RStations_Enter, sizeof(TI_RStations)/sizeof(TI_RStations[0]), TI_RStations);

MAKE_MENU(Menu_Calendar, Menu_Calendar_Enter, sizeof(TI_Calendar)/sizeof(TI_Calendar[0]), TI_Calendar);

int main(void)
{
#ifndef ATMEGA 
	CLKSYS_Enable(OSC_PLLEN_bm);
	CLKSYS_PLL_Config(OSC_PLLSRC_RC2M_gc, 16);
	while(CLKSYS_IsReady(OSC_PLLRDY_bm) == 0);
	CLKSYS_Main_ClockSource_Select(CLK_SCLKSEL_PLL_gc);
	
	TCE1.CTRLA = 0x05;      // Prescaler: clk/64
    TCE1.PER   = 15624;     // 32Hz
    TCE1.INTCTRLA = 0x02;   // Timer overflow is a medium level interrupt
#endif
	
#ifdef ATMEGA
	power_timer0_enable();
	power_timer1_enable();
	TCCR0A |= (1 << WGM01); // CTC mode
	TIMSK0 |= (1 << OCIE0A); // enable interrupt
	TCNT0 = 0;
	OCR0A = 0xFF;
	//TCCR0B = (1 << CS00)|(1 << CS02); // start timer, 1024 prescaler
	
	TCCR1B |= (1 << WGM12)|(1 << CS11)|(1 << CS10);
	TCNT1 = 0;
	OCR1A = 0x0C34;
	TIMSK1 |= (1 << OCIE1A);
#endif
	
	SSD1289_Init();
	SSD1289_Clear();
	//TWI_MasterInit(&gTWI_Master, &GLOBAL_TWI, TWI_MASTER_INTLVL_OFF_gc, GLOBAL_TWI_BAUD);
	//MCP79410_Init();
	//gRTC = MCP79410_Get();
	//TMP431_Init();
	ADS7843_Init();
	//VS1003_Init();
	
	FATFS FileSystemObject;
	if(f_mount(0, &FileSystemObject) != FR_OK)
		SSD1289_PrintString("oh shit\n", &gP1, &tahoma20ptFontInfo);
	
	DSTATUS driveStatus = disk_initialize();
	if((driveStatus & STA_NOINIT) || (driveStatus & STA_NODISK) || (driveStatus & STA_PROTECT))
		SSD1289_PrintString("oh shit2\n", &gP1, &tahoma20ptFontInfo);
	
	//MP3_ScanFiles();
	
	gRTC.hours = 12; gRTC.minutes = 55; gRTC.date = 7; gRTC.month = 7; gRTC.year = 12; gRTC.day = 5;
	gLocalTemperature.integer = -20; gRemoteTemperature.integer = 15;
	
	point screen[10]; // for gesture detection
	
	strcpy(gVS1003FileInfo.artistName, "Wybierz");
	strcpy(gVS1003FileInfo.songName, "utwor");
	
	gStatus = TOUCHSCREEN_IDLE | PLAYER_STOP;
	gGesture = GESTURE_NONE;
	
	InitAllMenus();
	drawInfoBar();
	SET_MENU(Menu_Main);
	
	sei();
    while(1)
    {
		if(gStatus & TOUCHSCREEN_IDLE) {
			asm volatile ("nop");
		}
		if(gStatus & TOUCHSCREEN_READ) {
			if(bit_is_clear(ADS7843_INT_PIN, ADS7843_INT_BIT)) {
				screen[screenCount] = ADS7843_GetSamples();
				screenCount++;
			}
			if(screenCount >= 10 || bit_is_set(ADS7843_INT_PIN, ADS7843_INT_BIT)) {
				TCCR0B = 0;
				ADS7843_DetectGesture(screenCount-5, &screen[5]);
				screenCount = 0;
			}
			gStatus &= ~TOUCHSCREEN_READ;
			gStatus |= TOUCHSCREEN_IDLE;
		}
		// rest of gStatus ifs come here
		if(gGesture == GESTURE_POINT) {
			if(CurrMenuItem == &Menu_Calendar) {
				/* normally I would create array of TouchItem elements and iterate through them
				to find correct coordinate. in case of calendar, array should consists of 42 items - that's way
				too much for this little poor ATmega644PA and possibly even for ATxmega128A3. 
				so, i'm going to manually check where press occurred and take appropriate action - all without use of TouchItem array.
				I assume, that every cell containing one date is about 30 pixels wide and 28 high.*/
				
			} else {
				TouchItem *ti = &ITEMSARRAY;
				uint8_t itemsNum = ITEMSNUM;
				for(uint8_t i = 0; i < itemsNum; i++) {
					if(isPointInRange(&screen[8], &(ti->Start), &(ti->End))) {
						((FuncPtr)ti->TouchFunc)();
						break;
					}
					ti++;
				}
			}
			gGesture = GESTURE_NONE;
			EIMSK |= (1 << INT1);
		} else if(gGesture == GESTURE_UP) {
			if(CurrMenuItem == &Menu_Artists) {
				if(mArtistsCurrentPage >= 1) {
					mArtistsCurrentPage--;
					Menu_Artists_Refresh();
				 } else {
					mArtistsCurrentPage = 0;
				 }					
			} else if(CurrMenuItem == &Menu_Songs) {
				if(mSongsCurrentPage >= 1) {
					mSongsCurrentPage--;
					Menu_Songs_Refresh();
				} else {
					mSongsCurrentPage = 0;
				}
			} else if(CurrMenuItem == &Menu_RStations) {
				if(mRStationsCurrentPage >= 1) {
					mRStationsCurrentPage--;
					Menu_RStations_Refresh();
				} else {
					mRStationsCurrentPage = 0;
				}
			} else if(CurrMenuItem == &Menu_Calendar) {
				if(mCalendarMonthToDisplay >= 2) {
					mCalendarMonthToDisplay--;
					Menu_Calendar_Refresh();
				}
			}							
			gGesture = GESTURE_NONE;
			EIMSK |= (1 << INT1);
		} else if(gGesture == GESTURE_DOWN) {
			if(CurrMenuItem == &Menu_Artists) {
				if(mArtistsCurrentPage <= 254) {
					mArtistsCurrentPage++;
					Menu_Artists_Refresh();
				}				
			} else if(CurrMenuItem == &Menu_Songs) {
				if(mSongsCurrentPage <= 254) {
					mSongsCurrentPage++;
					Menu_Songs_Refresh();
				}
			} else if(CurrMenuItem == &Menu_RStations) {
				if(mRStationsCurrentPage <= 254) {
					mRStationsCurrentPage++;
					Menu_RStations_Refresh();
				}
			} else if(CurrMenuItem == &Menu_Calendar) {
				if(mCalendarMonthToDisplay <= 11) {
					mCalendarMonthToDisplay++;
					Menu_Calendar_Refresh();
				}
			}
			gGesture = GESTURE_NONE;
			EIMSK |= (1 << INT1);
		} else if(gGesture == GESTURE_LEFT) {
			gGesture = GESTURE_NONE;
			EIMSK |= (1 << INT1);
		} else if(gGesture == GESTURE_RIGHT) {
			if(CurrMenuItem == &Menu_Artists) {
				Menu_Main_Enter();
			} else if(CurrMenuItem == &Menu_Songs) {
				Menu_Artists_Refresh();
				mSongsCurrentPage = 0;
			} else if(CurrMenuItem == &Menu_Player) {
				if(mPlayerGoBackToMain)
					Menu_Main_Enter();
				else
					Menu_Songs_Refresh();
			} else if(CurrMenuItem == &Menu_RStations) {
				Menu_Main_Enter();
			} else if(CurrMenuItem == &Menu_Calendar) {
				Menu_Main_Enter();
			}
			gGesture = GESTURE_NONE;
			EIMSK |= (1 << INT1);
		} else if(gGesture == 0) { // bad touch hurts entire execution time
			gGesture = GESTURE_NONE;
			EIMSK |= (1 << INT1);
		}
	}
}	

#ifndef ATMEGA
ISR(PORTC_INT1_vect) { // RTC interrupt
	
}

ISR(PORTE_INT0_vect) { // VS1003 interrupt (DREQ went high), high priority
}

ISR(DMA_CH0_vect) {
	// read to first buffer
}

ISR(DMA_CH1_vect) {
	// read to second buffer
}
#endif

#ifdef ATMEGA
ISR(INT1_vect) {
	for(uint8_t i = 0; i < 128; i++) { // little debouncing
		if(bit_is_set(ADS7843_INT_PIN, ADS7843_INT_BIT))
			return;
	}
	if(gStatus & TOUCHSCREEN_IDLE && gGesture == GESTURE_NONE) {
		TCCR0B = (1 << CS00)|(1 << CS02); // start timer, 1024 prescaler
		gStatus &= ~TOUCHSCREEN_IDLE; // remove idle flag
		gStatus |= TOUCHSCREEN_READ; // add read flag
		EIMSK &= ~(1 << INT1); // disable this interrupt
	}
}

ISR(TIMER0_COMPA_vect){
	if(gStatus & TOUCHSCREEN_IDLE && gGesture == GESTURE_NONE) {
		gStatus &= ~TOUCHSCREEN_IDLE; // remove idle flag
		gStatus |= TOUCHSCREEN_READ; // add read flag
	}
}

#endif